package com.bj58.ecdata.dashboard.databll;

import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ObjectUtils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bj58.ecdata.dashboard.cache.ServiceBeanFactory;
import com.bj58.ecdata.dashboard.constant.EnumCate;
import com.bj58.ecdata.dashboard.constant.InfoConst;
import com.bj58.ecdata.dashboard.constant.InfoSourceConst;
import com.bj58.ecdata.dashboard.dbentity.InfoCore;
import com.bj58.ecdata.dashboard.dbentity.InfoPostRate;
import com.bj58.ecdata.dashboard.dbentity.InfoResume_age;
import com.bj58.ecdata.dashboard.dbentity.InfoSource;
import com.bj58.ecdata.dashboard.service.AbstractBaseService;
import com.bj58.ecdata.dashboard.utils.DDateUtils;
import com.bj58.ecdata.dashboard.utils.DNumberUtils;
import com.bj58.ecdata.dashboard.utils.ReflectUtil;
import com.bj58.ecdata.dashboard.utils.VelocityTools;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;

public class DatainfoBLL {

	private static AbstractBaseService<InfoCore> infoService =ServiceBeanFactory.get(InfoCore.class,null);
	private static AbstractBaseService<InfoPostRate> infoPostService =ServiceBeanFactory.get(InfoPostRate.class,null);

	/**
	 * 查询某日信息量总体情况并计算日环比 周同比 月同比
	 * @author zhaoxiang 2015-07-21
	 */
	public static List<List<Object>> getGeneral(String date, EnumCate cate) {
		if (date == null || cate == null) {
			return Collections.emptyList();
		}
		String lastDay = DDateUtils.varDate(date, "yyyy-MM-dd", Calendar.DATE, -1);// 计算日环比
		String lastWeek = DDateUtils.varDate(date, "yyyy-MM-dd", Calendar.DATE, -7);// 计算日环比
		String lastMonth = DDateUtils.varDate(date, "yyyy-MM-dd", Calendar.DATE, -28);// 计算月同比 , 按28天算，刚好4周

		final String PATTEN_GENERAL = "(stat_date = '%s' OR stat_date='%s' OR stat_date='%s' OR stat_date='%s') AND business_name='%s' AND cate1_name='all'";
		
		String condition = String.format(PATTEN_GENERAL, date, lastDay, lastWeek, lastMonth, cate.getDBName());
		List<InfoCore> list = infoService.getListByConditon(null, condition, null);
		TreeMap<String, List<InfoCore>> map = ReflectUtil.groupByField(list,"stat_date");
		
		String[] roles = {"all","个人","免费商家","VIP"};
		String[] cols = {"info_valid_add_count","user_valid_add_count"};
		String[] dates = {date, lastDay, lastWeek, lastMonth};
		
		List<List<Object>> finalData = Lists.newArrayList(); //最终结果
		List<InfoCore> todayData = map.get(date);
		//遍历查询结果，处理数据
		for(String d : dates){
			List<InfoCore> curData = map.get(d);
			List<Object> tmpList = Lists.newArrayList();
			for(String type : roles){
				InfoCore vo = ReflectUtil.getByColVal(InfoCore.class, curData, "user_type_name", type);
				InfoCore todayVo = ReflectUtil.getByColVal(InfoCore.class, todayData, "user_type_name", type);
				for(String c : cols){
					Object val = ReflectUtil.getVal(vo, c);
					if(StringUtils.equals(date, d)){
						tmpList.add(val);
					}else{
						Object todayVal = ReflectUtil.getVal(todayVo, c);
						tmpList.add(VelocityTools.compRatio(todayVal, val));
					}
				}
			}
			//获得一行结果
			finalData.add(tmpList);
		}

		return finalData;
	}
	
	
	
	/**
	 * 业务线新增信息量总体趋势图 返回json对象{time:[],info_valid_add_count:[],user_valid_add_count:[] }
	 * @author zhaoxiang 2015-07-21
	 */
	public static String getLine_Day(EnumCate cate,String dateGroup) {
		List<InfoCore> list = infoService.getListByConditon(InfoConst.getLineCols(dateGroup), InfoConst.getLineCon(cate.getDBName(), dateGroup), dateGroup);
		
		List<Object> days = Lists.newArrayList();
		List<Object> infoCountList = Lists.newArrayList();
		List<Object> userCountList = Lists.newArrayList();
		for (InfoCore vo : list) {
			days.add(ReflectUtil.getVal(vo, dateGroup));
			infoCountList.add(ReflectUtil.getVal(vo, "info_valid_add_count"));
			userCountList.add(ReflectUtil.getVal(vo, "user_valid_add_count"));
		}

		JSONObject ob = new JSONObject();
		ob.put("time", days);
		ob.put("info_valid_add_count", infoCountList);
		ob.put("user_valid_add_count", userCountList);

		return ob.toString();
	}


	/**
	 * 个人，免费商家，VIP 总体趋势图 返回json对象{time:[],个人:[],免费商家:[] }
	 * @author zhaoxiang 2015-07-22
	 */
	public static String getUserTypeLineJson(EnumCate cate,
			String dateGroup, String indexType) {
		List<InfoCore> list = infoService.getListByConditon(InfoConst.getUserTypeCols(indexType ,"user_type_name",dateGroup), InfoConst.getUserTypeCon(cate.getDBName(), dateGroup), null);
		TreeMap<String, List<InfoCore>> stat_dateMap = new TreeMap<String, List<InfoCore>>(ReflectUtil.groupByField(list,dateGroup));
		
		Multimap<String, Object> dataMap= ArrayListMultimap.create();
		String[] roles = {"个人","免费商家","VIP"};
		for (String date : stat_dateMap.keySet()) {
			List<InfoCore> dayList = stat_dateMap.get(date);
			for(String r: roles){
				InfoCore vo = ReflectUtil.getByColVal(InfoCore.class, dayList, "user_type_name", r);
				dataMap.put(r, ReflectUtil.getVal(vo, indexType));
			}
		}

		JSONObject ob = new JSONObject();
		ob.put("time", stat_dateMap.keySet());
		ob.putAll(dataMap.asMap());

		return ob.toString();
	}
	
	
	/**
	 * 业务线信息量趋势 返回json对象{time:[],招聘:[],黄页:[] }
	 * @author zhaoxiang 2015-07-22
	 */
	public static String getBusinessLineJson(EnumCate cate,
			String dateGroup, String indexType,String userType) {
		List<?> cates = InfoConst.getCateListByBusiness(cate.name());
		String keyCol = "business_name";
		String condition = null;
		String CON_PTN = "business_name!='all' AND cate1_name='all' AND user_type_name='%s' group by %s,business_name";
		condition = String.format(CON_PTN,userType, dateGroup);
		
		List<InfoCore> list = infoService.getListByConditon(InfoConst.getUserTypeCols(indexType ,keyCol,dateGroup), condition, null);
		TreeMap<String, List<InfoCore>> stat_dateMap = new TreeMap<String, List<InfoCore>>(ReflectUtil.groupByField(list,dateGroup));
		
		Multimap<String, Object> dataMap= ArrayListMultimap.create();
		for (String date : stat_dateMap.keySet()) {
			List<InfoCore> dayList = stat_dateMap.get(date);
			for(Object r: cates){
				InfoCore vo = ReflectUtil.getByColVal(InfoCore.class, dayList, keyCol, r);
				Object val = ReflectUtil.getVal(vo, indexType);
				dataMap.put(r.toString(), val == null ? 0 : val);
			}
		}
		
		JSONObject ob = new JSONObject();
		ob.put("time", stat_dateMap.keySet());
		ob.putAll(dataMap.asMap());
		
		return ob.toString();
	}
	
	/**
	 * 重点类别信息量趋势 
	 * @return {time:[],info_valid_add_count:[],user_valid_add_count:[] }
	 * @author zhaoxiang 2015-07-22
	 */
	public static String getCateLineJson(EnumCate cate,
			String dateGroup, String cate2Name,String userType) {
		String CON_PTN = "business_name='%s' AND cate2_name ='%s' AND user_type_name='%s' group by %s,cate2_name";
		String condition = String.format(CON_PTN,cate.getDBName(), cate2Name, userType, dateGroup);
		
		List<InfoCore> list = infoService.getListByConditon(InfoConst.getLineCols(dateGroup), condition , dateGroup);
		
		List<Object> days = Lists.newArrayList();
		List<Object> infoCountList = Lists.newArrayList();
		List<Object> userCountList = Lists.newArrayList();
		for (InfoCore vo : list) {
			days.add(ReflectUtil.getVal(vo, dateGroup));
			infoCountList.add(ReflectUtil.getVal(vo, "info_valid_add_count"));
			userCountList.add(ReflectUtil.getVal(vo, "user_valid_add_count"));
		}

		JSONObject ob = new JSONObject();
		ob.put("time", days);
		ob.put("info_valid_add_count", infoCountList);
		ob.put("user_valid_add_count", userCountList);

		return ob.toString();
	}

	
	
	/**
	 * 信息来源  “饼图” 
	 * @return
	 * @author zhaoxiang 2015-07-23
	 */
	public static String getSourcePieDataJson(EnumCate cate,String beginDate,String userType, String indexType){
		JSONArray source1List = InfoSourceConst.platList;
		
//		Class<InfoSource> beanClas= InfoSourceConst.getBeanCls(cate);
		AbstractBaseService<InfoSource>  ifs = ServiceBeanFactory.get(InfoSource.class,null); //busEnum.getCityCateService();
		String tableSuffix = cate.name();
		if(EnumCate.total == cate){
			tableSuffix="all";
		}
		List<InfoSource> list = ifs.getListByConditon(tableSuffix,InfoConst.getUserTypeCols(indexType,"source_name","platform"), InfoConst.getSourceTwoPieCon(beginDate, userType), null);
		
		JSONObject jsonObject = new JSONObject(); 	//{source1NameList: [], source1_JSONArray:[{},{}], {source1: {source2NameList: [], source2_JSONArray:[]}} }
		int maxVal1 = 0;
		JSONArray source1_JSONArray = new JSONArray();	//[{},{}]
		
		TreeMap<String, List<InfoSource>> source1_dateMap = new TreeMap<String, List<InfoSource>>(ReflectUtil.groupByField(list,"platform"));
		for (String  source1: source1_dateMap.keySet()) {
			JSONObject source1JSON = new JSONObject();
			
			JSONObject source2JSONObj = new JSONObject(); //{source2NameList: [], source2_JSONArray:[{},{}]}
			Set<Object> source2NameSet = Sets.newHashSet();
			JSONArray source2_JSONArray = new JSONArray();
			
			
			int maxVal2 = 0;
			List<InfoSource> source2_list = source1_dateMap.get(source1);
			for(InfoSource source2Vo : source2_list){
				 Object source2NameObject = ReflectUtil.getVal(source2Vo, "source_name");
				 Integer value = (Integer)ReflectUtil.getVal(source2Vo, indexType);
				 
				if(ObjectUtils.equals(source2NameObject,"all")){
					source1JSON.put("name",source1);
					source1JSON.put("value",value);
					int val1 = (int) Math.ceil(value);
					if(maxVal1 < val1){
						maxVal1 = val1;
					}
					if(source2_list.size() == 1){
						source2NameObject = source1;
					}else{
						continue;
					}
				}
				source2NameSet.add(source2NameObject);
				JSONObject source2JSON = new JSONObject();
				source2JSON.put("name", source2NameObject);
				source2JSON.put("value", value);
				int val2 = (int) Math.ceil(value);
				if(maxVal2 < val2){
					maxVal2 = val2;
				}
				source2_JSONArray.add(source2JSON);
			}
			source2JSONObj.put("source2NameList", source2NameSet);
			source2JSONObj.put("source2DataList", source2_JSONArray);
			source2JSONObj.put("max", maxVal2);
			jsonObject.put(source1, source2JSONObj);
			if(source1List.contains(source1JSON.get("name"))){
				source1_JSONArray.add(source1JSON);
			}
		}

		jsonObject.put("source1NameList", source1List);
		jsonObject.put("source1DataList", source1_JSONArray);
		jsonObject.put("max", maxVal1);
		jsonObject.put("beginDate", beginDate);

		return jsonObject.toString();
	}


	/**
	 * 分平台,来源,类别 曲线图
	 * @return
	 */
	public static String getPlatCateSrcJson(Map<String, String> paramsMap) {
		EnumCate cate = EnumCate.valueOf(paramsMap.get("businessName"));
		String dateGroup = paramsMap.get("dateGroup");
		String platform = paramsMap.get("platform");
		
		String CON_PTN = "cate2_name='all' AND source_name!='all' AND platform='%s' AND user_type_name='%s' AND stat_type='%s' group by %s,source_name";
		String condition = String .format(CON_PTN,  platform,  paramsMap.get("userType"), paramsMap.get("statType"), paramsMap.get("dateGroup"));
		String cols = dateGroup + ",source_name,info_valid_add_count,user_valid_add_count";
		
		AbstractBaseService<InfoSource>  ifs = ServiceBeanFactory.get(InfoSource.class,null); //busEnum.getCityCateService();
		String tableSuffix = cate.name();
		if(EnumCate.total == cate){
			tableSuffix="all";
		}
		List<InfoSource> list = ifs.getListByConditon(tableSuffix,cols,condition,  null);

		TreeMap<String, List<InfoSource>> stat_dateMap = new TreeMap<String, List<InfoSource>>(ReflectUtil.groupByField(list,dateGroup));
		
		Multimap<String, Object> finalData = ArrayListMultimap.create();
		List<Object> sourceList = InfoSourceConst.getSources(platform);
		for (String date : stat_dateMap.keySet()) {
			List<InfoSource> valList =  stat_dateMap.get(date);
			for(Object src : sourceList){
				Object vo =  ReflectUtil.getByColVal(InfoSource.class, valList, "source_name", src);
				finalData.put(src.toString(),ReflectUtil.getVal(vo, paramsMap.get("indexType")));
			}
		}
		
		JSONObject ob = new JSONObject();
		ob.put("legend", sourceList);
		ob.put("time", stat_dateMap.keySet());
		ob.putAll(finalData.asMap());
		
		return ob.toString();
	}
	
	
	/**
	 * 简历新增趋势图
	 * @author zhaoxiang 2015-07-22
	 */
	public static String getResumeAddJson(String data_group,  String indexType) {
		String CON_PTN = "target_cate2='%s' group by %s";
		String condition = String.format(CON_PTN, indexType,data_group);
		String cols = data_group+",sum(add_count)/count(distinct stat_date) as value,sum(user_count)/count(distinct stat_date) as user_count";
		Class<?> beanClas= InfoResume_age.class;
		AbstractBaseService<?>  service = ServiceBeanFactory.get(beanClas,null);
		List<?> list = service.getListByConditon(cols, condition, data_group);
		
		List<Object> valList = Lists.newArrayList();
		List<Object> userCountList = Lists.newArrayList();
		List<Object> dayList = Lists.newArrayList();
		for(Object vo: list){
			valList.add(ReflectUtil.getVal(vo, "value"));
			userCountList.add(ReflectUtil.getVal(vo, "user_count"));
			dayList.add(ReflectUtil.getVal(vo, data_group));
		}
		
		JSONObject ob = new JSONObject();
		
		ob.put("time", dayList);		
		ob.put("add_count", valList);
		ob.put("user_count", userCountList);
		
		return ob.toString();
	}
	
	/**
	 * 简历人群分布饼图
	 * @param industry 
	 * @param indexType 
	 * @param endDate 
	 * @param beginDate 
	 * @return
	 */
	public static String getResumeCrowdJson(String beginDate,String endDate, String indexType, String industry){
		List<Object> cateList = InfoConst.getCrowdCateList(indexType);;
		
		String CON_PTN = "stat_date>='%s' AND stat_date<='%s' AND target_cate2='%s' AND %s!='all' group by %s";
		String condition = String.format(CON_PTN, beginDate, endDate, industry, indexType,indexType);
		String cols = String.format("%s as indexType,sum(user_count) as value", indexType);
		Class<?> beanClas= InfoConst.getResumeBeanClass(indexType);
		AbstractBaseService<?>  service = ServiceBeanFactory.get(beanClas,null);
		List<?> list = service.getListByConditon(cols, condition,null);		
		
		long maxVal = 0;
		JSONArray cate_JSONArray = new JSONArray();	//[{},{}]
		
		for (Object  vo : list) {
			Object name = ReflectUtil.getVal(vo,"indexType");
			Long value = (Long)ReflectUtil.getVal(vo, "value");
			JSONObject json = new JSONObject();
			json.put("name",name);
			json.put("value",value);
			cate_JSONArray.add(json);
			if(maxVal < value){
				maxVal = value;
			}
		}
		JSONObject jsonObject = new JSONObject(); 
		jsonObject.put("nameList", cateList);
		jsonObject.put("data", cate_JSONArray);
		jsonObject.put("max", maxVal);
	
		return jsonObject.toString();
	}

//	/**
//	 * 平台，业务线发布成功率多维柱状图
//	 * @param endDate 
//	 * @param beginDate 
//	 * @return
//	 */
//	public static String platPostRate(String indexType, String beginDate, String endDate) {
//		List<String> cateList = Lists.newArrayList("招聘","房产","黄页","二手","二手车");
//		List<String> platList = ImmutableList.of("PC","M","APP");
//		String cols = "business_name,platform,";
//		if(StringUtils.equals("post_rate", indexType )){
//			cols += "sum(success_pv)*100/sum(fill_pv) as post_rate";
//		}else if(StringUtils.equals("nologin_post_rate", indexType )){
//			cols += "sum(success_pv)*100/sum(fill_pv) as nologin_post_rate";
//		}
//		String condition = String.format(platPostRateCON, beginDate, endDate);
////		List<InfoPostRate> list = infoPostService.getListByConditon(cols,condition, null);
////		TreeMap<String, List<InfoPostRate>> stat_dateMap = new TreeMap<String, List<InfoPostRate>>(ReflectUtil.groupByField(list,"platform"));
//		
//		JSONObject jsonObject = new JSONObject();	//[{},{}]
//		
//		Random random = new Random();
//		// vppv/uv比较特殊
//		for (String  plat : platList) {
//			List<Object> curList = Lists.newArrayList();
////			List<InfoPostRate> voList = stat_dateMap.get(plat);
////			if(curList == null)
////				voList = Collections.emptyList();
//			for (String  cate : cateList) {
//				InfoPostRate vo = new InfoPostRate(cate,plat, (int)(20 + random.nextInt(80)));
////				InfoPostRate vo = ReflectUtil.getByColVal(InfoPostRate.class, voList, "business_name", cate);
//				Object val = ReflectUtil.getVal(vo,indexType);
//				curList.add(val);
//			}
//			jsonObject.put(plat, curList);
//		}
//		
//		return jsonObject.toString();
//	}

	private static final String platPostRateCON = "business_name='%s' AND cate_name='%s' AND platform='%s'  group by stat_date";

	/**
	 * 发布成功率
	 * @return
	 */
	public static String catePostRate(String businessName,String platform,String cateName, String indexType) {
		String cols = null;
		if(StringUtils.equals("post_rate", indexType )){
			cols = "stat_date,success_pv,fill_pv,sum(success_pv)*100/sum(fill_pv) as post_rate";
		}else if(StringUtils.equals("nologin_post_rate", indexType )){
			cols = "stat_date,nologin_success_pv as success_pv,nologin_fill_pv as fill_pv,sum(nologin_success_pv)*100/sum(nologin_fill_pv) as post_rate";
		}
		String condition = String.format(platPostRateCON, businessName,cateName, platform);
		List<InfoPostRate> list = infoPostService.getListByConditon(cols,condition, "stat_date");
		
		JSONObject jsonObject = new JSONObject();	//[{},{}]

		List<Object> rateList = Lists.newArrayList();
		List<Object> fillPVList = Lists.newArrayList();
		List<Object> successPVList = Lists.newArrayList();
		List<String> days = Lists.newArrayList();
		for (InfoPostRate vo: list) {
			days.add(vo.getStat_date());
			rateList.add(DNumberUtils.format(vo.getPost_rate()));
			fillPVList.add(vo.getFill_pv());
			successPVList.add(vo.getSuccess_pv());
		}
		jsonObject.put("time", days);
		jsonObject.put("rate", rateList);
		jsonObject.put("fillPVList", fillPVList);
		jsonObject.put("successPVList",successPVList );
		return jsonObject.toString();
	}
	
}
